var puppeteer = require("puppeteer");

// In-memory cache of rendered pages. Note: this will be cleared whenever the
// server process stops. If you need true persistence, use something like
// Google Cloud Storage (https://firebase.google.com/docs/storage/web/start).
const RENDER_CACHE = new Map();
let WSE_LIST = {};
let PAG_LIST = {};
let sourceTime =  new Date().valueOf()
// browser 初始化，将bwse存储复用
// 我这里只起了一个进程，如果机器性能好的话可以启多几个，不过切记不要太多
/*(async() =>{
  // 因为服务器内核不支持sandbox，所以只能启用--no-sandbox
  // --no-first- run 可以减少第一个标签页开启的时间
  // 更多参数可以参考https://peter.sh/experiments/chromium-command-line-switches/

  // 存储节点以便能重新连接到 Chromium

})();*/

async function ssr(url) {
  console.log("url", url);

  if (RENDER_CACHE.has(url)) {
    return { html: RENDER_CACHE.get(url), ttRenderMs: 0 };
  }
  let browserWSEndpoint
  const start = Date.now();
  if(WSE_LIST[url]){
    browserWSEndpoint = WSE_LIST[url]
    console.log('1');
  }else {
    const browser1 = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox','--no-first-run']});
    browserWSEndpoint = await browser1.wsEndpoint();
    WSE_LIST[url] = browserWSEndpoint
    console.log('2');
  }
// 恢复节点
  const browser = await puppeteer.connect({browserWSEndpoint});
  let  page
  let tiem = new Date().valueOf()
  if (tiem - sourceTime > 5 * 6000 && PAG_LIST[url]) {
    PAG_LIST[url].close().then(()=>{
      PAG_LIST[url] = null
      sourceTime =  new Date().valueOf()
    }).catch((e)=>{
      console.error(e);
    })
  }
  if(PAG_LIST[url]){
    page = PAG_LIST[url]
  }else {
    // 开新页面记录时间
    page = await browser.newPage();
    PAG_LIST[url] = page
  }
  await page.setJavaScriptEnabled(true);
  // 由于只关心渲染后的dom树，所以对css，font，image等都做了屏蔽
  await page.setRequestInterception(true);
  page.on('request', (req) => {
    if(req.resourceType() == 'stylesheet' || req.resourceType() == 'font' || req.resourceType() == 'image'){
      req.abort();
    } else {
      req.continue();
    }
  })
  try {
    // networkidle0 waits for the network to be idle (no requests for 500ms).
    // The page's JS has likely produced markup by this point, but wait longer
    // if your site lazy loads, etc.
    await page.goto(url, { waitUntil: ['load','domcontentloaded','networkidle2'] });
    // await page.waitForSelector("#posts"); // ensure #posts exists in the DOM.
  } catch (err) {
    console.error(err);
    throw new Error("page.goto/waitForSelector timed out.");
  }

  let html = await page.content(); // serialized HTML of page DOM.
  await browser.close();

  const ttRenderMs = Date.now() - start;
  console.info(`Headless rendered page in: ${ttRenderMs}ms`);

  RENDER_CACHE.set(url, html); // cache rendered page.

  return { html, ttRenderMs };
}

module.exports = ssr;
